package com.hk.blog.service.impl;

import com.hk.blog.domain.ArticleInfo;
import com.hk.blog.repository.jpa.ArticleInfoRepository;
import com.hk.blog.service.ArticleInfoService;
import com.hk.blog.service.CategoryInfoService;
import com.hk.blog.vo.ArticleListVo;
import com.hk.blog.vo.ArticleSearchBean;
import com.hk.commons.query.QueryModel;
import com.hk.commons.query.page.QueryPage;
import com.hk.commons.util.ObjectUtils;
import com.hk.core.data.jpa.repository.BaseJpaRepository;
import com.hk.core.service.exception.ServiceException;
import com.hk.core.service.jpa.impl.JpaServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

@Service
@RequiredArgsConstructor
public class ArticleInfoServiceImpl extends JpaServiceImpl<ArticleInfo, Long>
        implements ArticleInfoService {

    private final ArticleInfoRepository articleInfoRepository;

    private final CategoryInfoService categoryInfoService;

    @Override
    protected BaseJpaRepository<ArticleInfo, Long> getBaseRepository() {
        return articleInfoRepository;
    }

    @Override
    protected ExampleMatcher ofExampleMatcher() {
        return super.ofExampleMatcher()
                .withMatcher("userId", ExampleMatcher.GenericPropertyMatchers.exact())
                .withMatcher("categoryId", ExampleMatcher.GenericPropertyMatchers.exact())
                .withMatcher("protect", ExampleMatcher.GenericPropertyMatchers.exact())
                .withMatcher("title", ExampleMatcher.GenericPropertyMatchers.contains());
    }

    @Override
    public QueryPage<ArticleListVo> findForPage(QueryModel<ArticleSearchBean> queryModel) {
        return articleInfoRepository.findForPage(queryModel);
    }

    @Override
    @Transactional
    public void deleteById(Long id) {
        var articleInfo = articleInfoRepository.getById(id);
        categoryInfoService.subtractArticleNum(articleInfo.getCategoryId(), 1);
        articleInfoRepository.delete(articleInfo);
    }

    @Override
    @Transactional
    public ArticleInfo insert(ArticleInfo articleInfo) {
        var categoryInfo = categoryInfoService.findById(articleInfo.getCategoryId())
                .orElseThrow(() -> new ServiceException("类别不存在"));
        categoryInfo.setArticleNum(ObjectUtils.defaultIfNull(categoryInfo.getArticleNum(), 0) + 1);
        articleInfo.setBrowseNum(0);
        categoryInfoService.updateById(categoryInfo);
        return super.insert(articleInfo);
    }

    @Override
    @Transactional
    public ArticleInfo updateById(ArticleInfo articleInfo) {
        ArticleInfo find = articleInfoRepository.getReferenceById(articleInfo.getId());
        if (!Objects.equals(find.getCategoryId(), articleInfo.getCategoryId())) {
            categoryInfoService.subtractArticleNum(find.getCategoryId(), 1);
            categoryInfoService.addArticleNum(articleInfo.getCategoryId(), 1);
        }
        return super.updateById(articleInfo);
    }
}
